package com.gamejelly.proxy.server;

import com.gamejelly.proxy.pojo.RpcResponse;
import com.gamejelly.proxy.pojo.RpcCall;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;

/**
 * Created by haoyifen on 2017/6/16 11:30.
 */
@Sharable
public class RpcServerHandler extends SimpleChannelInboundHandler<RpcCall> {

    private static final Logger logger = LoggerFactory.getLogger(RpcServerHandler.class);
    @Setter
    private ServiceProvider serviceProvider;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcCall call) throws Exception {
        Object result = serviceProvider.invoke(call);
        if (result == null) {
            return;
        }
        if (result instanceof CompletableFuture) {
            ((CompletableFuture<?>) result).whenComplete((res, t) -> {
                RpcResponse response;
                if (t != null) {
                    logger.warn("rpc call fail {}", t.getMessage());
                    response = RpcResponse.fail(call.getId(), 1, t.getMessage());
                    return;
                } else
                    response = RpcResponse.ok(call.getId(), res);
                ctx.writeAndFlush(response);
            });
        } else {
            RpcResponse response = RpcResponse.ok(call.getId(), result);
            ctx.writeAndFlush(response);
        }

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.info("remote server connect : {}", ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }
}
